"use strict";

var router = require("router"),
    TokenService = require("router").TokenService,
    mongo = require('./core/mongoservice'),
    extensions = require('./core/extensions'),
    ObjectId = require('mongodb').ObjectID,
    Q = require('q');

function ShopReportService() {
    console.log("ShopReportService constructor");
}
ShopReportService.prototype = Object.create(TokenService.prototype);
ShopReportService.prototype.constructor = ShopReportService;

ShopReportService.prototype.getFromToken = function (request, response, promise) {
    return promise.then(function (self) {
        self.identify(request, response);
        var shopId = request.payload.shop.id;
        return self.mongoGetByShopId(shopId).then(function (report) {
            return response.send({ request: request, content: report });
        });
    });
};

/*-------------------------------------------------------*/
/*mongo daf*/

ShopReportService.prototype.mongoGetByShopId = function (shopId) {
    if (!shopId) throw new Error("shopId is not defined.");
    var self = this;

    return mongo.findOne('shops.reports', { "shop.id": new ObjectId(shopId) }).then(function (item) {
        item.reports = self.generate1YCountReports(item.reports); //replace reports
        return item;
    });
};

ShopReportService.prototype.mongoInsert = function (shop) {
    var self = this;

    var doc = {
        shop: { id: shop._id },
        reports: []
    };

    doc.reports.push(self.emptyReport());

    
    return mongo.insert('shops.reports', doc).then(function (docs) {
        return docs[0];
    }).then(function (doc) {
        return self.mongoUpdate(shop);
    });
};

ShopReportService.prototype.emptyReport = function () {
    var today = new Date();
    today.setHours(0, 0, 0, 0);

    return {
        date: today,
        users: {
            near: [],
            subscribers: []
        },
        shops: {
            near: [],
            subscribers: []
        },
        alerts: {
            total: []
        }
    };
};

ShopReportService.prototype.mongoPullCurrentReport = function (shopId) {
    var self = this;

    var report = self.emptyReport();
    var rp = {
        date: report.date
    };

    return mongo.update('shops.reports', { "shop.id": new ObjectId(shopId) }, { $pull: { "reports": rp} }, { multi: true }).then(function () {
        return report;
    });
};

ShopReportService.prototype.mongoPushCurrentReport = function (shopId, report) {
    var self = this;

    var shopId = new ObjectId(shopId);

    var previousDate = new Date(report.date);
    previousDate.setDate(previousDate.getDate() - 1)

    return mongo.findOne('shops.reports', { "shop.id": shopId }).then(function (item) {
        var lastReport = item.reports[item.reports.length - 1];

        if (lastReport == undefined) {
            var previousReport = self.emptyReport();
            previousReport.date = previousDate;

            return mongo.update('shops.reports', { "shop.id": shopId }, { $push: { "reports": previousReport} }).then(function () {
                return mongo.update('shops.reports', { "shop.id": shopId }, { $push: { "reports": report} });
            });
        }
        if (lastReport.date < previousDate) {
            var previousReport = extensions.clone(lastReport);
            previousReport.date = previousDate;

            return mongo.update('shops.reports', { "shop.id": shopId }, { $push: { "reports": previousReport} }).then(function () {
                return mongo.update('shops.reports', { "shop.id": shopId }, { $push: { "reports": report} });
            });
        }
        else
            return mongo.update('shops.reports', { "shop.id": shopId }, { $push: { "reports": report} });
    });


}

ShopReportService.prototype.mongoUpdate = function (shop) {
    var self = this;
    return self.mongoPullCurrentReport(shop._id).then(function (report) {

        report.users = shop.users;
        report.shops = shop.shops;
        report.alerts = shop.alerts;

        return self.mongoPushCurrentReport(shop._id, report);
    });
}


/*-------------------------------------------------------*/
/*common*/
ShopReportService.prototype.generateCountReport = function (report) {
    if (!report) throw new Error("report is not defined.");

    var usersNearTotal = report.users.near.length;
    var usersSubscribersTotal = report.users.subscribers.length;
    var alertsTotal = report.alerts.total;

    return {
        date: report.date,
        users: {
            near: {
                total: usersNearTotal
            },
            subscribers: {
                total: usersSubscribersTotal
            }
        },
        alerts: {
            total: alertsTotal
        }
    };
};

ShopReportService.prototype.generateEmptyCountReport = function (date) {
    var usersNearTotal = 0;
    var usersSubscribersTotal = 0;
    var alertsTotal = 0;

    return {
        date: date,
        users: {
            near: {
                total: usersNearTotal
            },
            subscribers: {
                total: usersSubscribersTotal
            }
        },
        alerts: {
            total: alertsTotal
        }
    };
};

ShopReportService.prototype.generate1YCountReports = function (reports) {
    if (!reports) throw new Error("reports is not defined.");
    var self = this;

    var today = new Date();

    var startDate = new Date();
    startDate.setHours(0, 0, 0, 0);
    startDate.setMonth(startDate.getMonth() - 6);

    var userReports = [];
    reports.forEach(function (report) {
        if (report.date > startDate)
            userReports.push(self.generateCountReport(report));
    });

    var firstReport = extensions.clone(userReports[0]);
    firstReport.date = startDate;
    userReports.splice(0, 0, firstReport);

    var todayReport = extensions.clone(userReports[userReports.length - 1]);
    todayReport.date = today;
    userReports.push(todayReport);

    return userReports;
};

exports = module.exports = new ShopReportService();